#ifndef BOIDS_H
#define BOIDS_H
#include "globals.h"


class BoidVec3d;    //forward decleration

class BoidPosition3d
{
public:

	float x;
	float y;
	float z;

	BoidPosition3d(){}
	
	BoidPosition3d(float a_x, float a_y, float a_z, bool randPos);

	float getDistance(BoidPosition3d& pos);

	void movePosition(BoidVec3d& vec);
};

inline BoidPosition3d convertIrrVecToBoidPos(irr::core::vector3df& vec)
{

	BoidPosition3d pos(vec.X, vec.Y, vec.Z, false);

	return pos;

}
class BoidVec3d
{
public:
	float x;
	float y;
	float z;
	
	
	BoidVec3d(float a_x, float a_y, float a_z);
	BoidVec3d(){}
	BoidVec3d(BoidPosition3d& startPos, BoidPosition3d& endPos);
	
	void printVec();
	void normalize();
	float length();
	BoidVec3d operator +(BoidVec3d& a_vec);
	BoidVec3d operator +=(BoidVec3d& a_vec);
	BoidVec3d operator /(float num);
	BoidVec3d operator /=(float num);
	BoidVec3d operator -(BoidVec3d& a_vec);
	BoidVec3d operator -=(BoidVec3d& a_vec);
	BoidVec3d operator *(float num);
	BoidVec3d operator *=(float num);
};

class Boid
{
public:
	
	irr::core::aabbox3d<f32> boundaryBox;
	BoidPosition3d location;
	BoidVec3d velocity;

	IAnimatedMeshSceneNode* node;

	Boid(){}
	Boid(const c8 *meshFilePath, const c8 *textureFilePath, irr::core::aabbox3d<f32>& containmentBox);

	void Boid::updateBoid(std::vector<Boid*> boidList, float cohesionRange,float cohesionScalingFactor, float seperationRange,
	float seperationScalingFactor, float alignmentRange, float alignmentScalingFactor,  int boidListLength);

	void limitSpeed(float sensitivity);
	void updateNode();
	void remainWithinBoundary(float responsiveness, float scalingFactor);

	BoidVec3d seperation(std::vector<Boid*> boidList, float range, float scalingFactor, int boidListLength);
	BoidVec3d alignment(std::vector<Boid*> boidList, float range, float scalingFactor, int boidListLength);
	BoidVec3d cohesion(std::vector<Boid*> boidList, float range, float scalingFactor, int boidListLength);

};

class EventReciever: public IEventReceiver
{
public:

	EventReciever();	

	virtual bool OnEvent(const SEvent& event);
};

void makeBoidGui(dimension2d<s32>& windowSize);
vector3df moveForwardRelativeToRotation(ICameraSceneNode* player, float elapsed, float distance);
vector3df updateCamTarget(ICameraSceneNode* cam, float distance, float timeElapsed);
void rotateCamWithMouse(ICameraSceneNode* cam, int mouseChangeX, int mouseChangeY, bool disableMouseMovement);
#endif